package com.atguigu.java.ai.langchain4j.tools;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.java.ai.langchain4j.entity.Appointment;
import com.atguigu.java.ai.langchain4j.service.AppointmentService;

import com.atguigu.java.ai.langchain4j.utils.HttpUtils;

import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;

import dev.langchain4j.service.V;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.util.HashMap;
import java.util.Map;

@Component
public class AppointmentTools {
    @Autowired
    private AppointmentService appointmentService;

    @Tool(name="预约挂号", value = "根据参数，先执行工具方法queryDepartment查询是否可预约，并直接给用户回答是否可预约，并让用户确认所有预约信息，用户确认后再进行预约。")
    public String bookAppointment(@P(value = "预约信息",required = true) Appointment appointment){
        System.out.println("===============调用预约挂号工具=================");
        //查找数据库中是否包含对应的预约记录
        Appointment appointmentDB = appointmentService.getOne(appointment);
        if(appointmentDB == null){
            appointment.setId(null);//防止大模型幻觉设置了id
            if(appointmentService.save(appointment)){
                String host ="http://localhost:8207/";
                String path ="auth/submitOrder/{scheduleId}/{patientId}";
                String method ="POST";
                Map<String,String> headers = new HashMap<>();
                Map<String,String> querys = new HashMap<>();
                Map<String,String> bodys = new HashMap<>();
                bodys.put("scheduleId",appointment.getDepartment());
                bodys.put("patientId",appointment.getId().toString());
                try {
                    HttpResponse response =HttpUtils.doPost(host, path,method,headers,querys,bodys);
                    HttpEntity entity = response.getEntity();
                    String result = EntityUtils.toString(entity,"UTF-8");
                    JSONObject jsonObject = JSONObject.parseObject(result);
                    Integer code = jsonObject.getInteger("code");
                    if(code == 200){
                        return "预约成功，并返回预约详情";
                    } else {
                        return "预约失败";
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return "预约成功，并返回预约详情";
            }else{
                return "预约失败";
            }
        }
        return "您在相同的科室和时间已有预约";
    }

    @Tool(name="取消预约挂号", value = "根据参数，查询预约是否存在，如果存在则删除预约记录并返回取消预约成功，否则返回取消预约失败")
    public String cancelAppointment(Appointment appointment){
        System.out.println("===============调用取消挂号工具=================");

        Appointment appointmentDB = appointmentService.getOne(appointment);
        if(appointmentDB != null){
            //删除预约记录
            if(appointmentService.removeById(appointmentDB.getId())){
                String host ="http://localhost:8207/";
                String path ="auth/cancelOrder/{orderId}";
                String method = "Get" ;//get请求
                Map<String,String> headers = new HashMap<>();
                Map<String,String> querys = new HashMap<>();
                Map<String,String> bodys = new HashMap<>();
                querys.put("orderId",appointmentDB.getId().toString());
                try {
                    HttpResponse response = HttpUtils.doGet(host, path,method,headers,querys);
                    HttpEntity entity = response.getEntity();
                    String string = EntityUtils.toString(entity, "UTF-8");
                    JSONObject jsonObject = JSONObject.parseObject(string);
                    Integer code = jsonObject.getInteger("code");
                    if(code == 200){
                        return "取消预约成功";
                    }

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                return "取消预约失败";
            }else{
                return "取消预约失败";
            }
        }
        //取消失败
        return "您没有预约记录，请核对预约科室和时间";
    }
//    查询是否有号源
    @Tool(name = "查询是否有号源",value = "根据参数，先执行工具方法queryDepartment查询是否可预约，并直接给\n" +
            "用户回答是否可预约，并让用户确认所有预约信息，用户确认后再进行预约。如果用户没有提供具体的医生姓名，请从\n" +
            "向量存储中找到一位医生。")
    public  boolean queryDepartment(
            @P(value = "科室名称",required = true) String name,
            @P(value = "日期",required = true) String date,
            @P(value = "时间：可选值：上午，下午")String time,
            @P(value = "医生名称",required = false) String doctorName) {
        System.out.println("查询是否有号源");
        System.out.println("科室名称：" + name);
        System.out.println("日期：" + date);
        System.out.println("时间：" + time);
        System.out.println("医生名称：" + doctorName);
        //TODO 维护医生的排班信息：

        //如果没有指定医生名字，则根据其他条件查询是否有可以预约的医生（有返回true，否则返回false）；

        //如果指定了医生名字，则判断医生是否有排班（没有排版返回false）

        //如果有排班，则判断医生排班时间段是否已约满（约满返回false，有空闲时间返回true）


        String host ="http://localhost:8201/";
        String path ="api/hosp/select";
        String method ="POST";

        Map<String,String> headers = new HashMap<>();
        Map<String,String> querys = new HashMap<>();
        Map<String,String> bodys = new HashMap<>();
        bodys.put("name",name);
        bodys.put("date",date);
        bodys.put("time",time);
        bodys.put("doctorName",doctorName);


        try {
            HttpResponse response =
                    HttpUtils.doPost(host, path,
                            method, headers, querys,
                            bodys);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity,"UTF-8");
            JSONObject jsonObject = JSONObject.parseObject(result);
            Integer code = jsonObject.getInteger("code");
            if(code == 200){
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

}
